package ochart.elements.axes
{
	import flash.display.Sprite;
	import flash.events.Event;
	
	import ochart.core.ChartObject;
	import ochart.elements.labels.Label;
	import ochart.utils.ArrayUtil;
	
	public class AxisBase extends ChartObject
	{
		public static const CLASS_NAME:String = "AxisBase"
		
		override public function get className():String
		{
			return CLASS_NAME;
		}
		
		public static const ALIAS:String = "axisBase";
		
		override public function get alias():String
		{
			return ALIAS;
		}
		
		public static const VALUES_NAME:String = "values";
		
		/**
		 * 忽略水平对齐属性
		 */
		override public function set align(value:String):void
		{
			
		}
		
		/**
		 * 忽略居中对齐属性
		 */
		override public function set valign(value:String):void
		{
			
		}
		
		private var _min:Number = 0;

		public function get min():Number
		{
			return _min;
		}

		public function set min(value:Number):void
		{
			_min = value;
			
			calculate();
		}

		private var _max:Number = 0;

		public function get max():Number
		{
			return _max;
		}

		public function set max(value:Number):void
		{
			_max = value;
			
			calculate();
		}

		private var _steps:Number = 0;

		public function get steps():Number
		{
			return _steps;
		}

		public function set steps(value:Number):void
		{
			_steps = value;
			
			calculate();
		}
		
		private var _stepLength:Number = 0;

		public function get stepLength():Number
		{
			return _stepLength;
		}
		
		public function set stepLength(value:Number):void
		{
			_stepLength = value;
		}

		private var _offset:Number = 0;

		public function get offset():Number
		{
			return _offset;
		}

		public function set offset(value:Number):void
		{
			_offset = value;
			
			calculate();
		}
		
		private var _barOffset:Number = 0;

		public function get barOffset():Number
		{
			return _barOffset;
		}

		public function set barOffset(value:Number):void
		{
			_barOffset = value;
			
			calculate();
		}
		
		private var _count:Number = 0;
		
		public function get count():Number
		{
			return _count;
		}
		
		public var ticksContainer:ChartObject = null;
		public var labelContainer:ChartObject = null;
		
		protected var isTicksChange:Boolean = false;
		private var _ticksArray:Array = [];

		public function get ticksArray():Array
		{
			return _ticksArray;
		}

		public function set ticksArray(value:Array):void
		{
			_ticksArray = value;
			
			isTicksChange = true;
			needUpdate = true;
		}
		
		private var _tickCount:int = 0;

		public function get tickCount():int
		{
			return _tickCount;
		}
		
		protected var isLabelsChange:Boolean = false;
		private var _labelValuesArray:Array = [];

		public function get labelValuesArray():Array
		{
			return _labelValuesArray;
		}

		public function set labelValuesArray(value:Array):void
		{
			_labelValuesArray = value;
			
			isLabelsChange = true;
			needUpdate = true;
		}

		private var _labelsArray:Array = [];

		public function get labelsArray():Array
		{
			return _labelsArray;
		}

		public function set labelsArray(value:Array):void
		{
			_labelsArray = value;
			
			isLabelsChange = true;
			needUpdate = true;
		}
		
		private var _labelCount:int = 0;
		
		public function get labelCount():int
		{
			return _labelCount;
		}
		
		private var defaultValue:Object = 
		{
			"min" : 0,
			"max" : 0,
			"steps" : 1,
			"offset" : 0
		}
			
		private var _propertiesArray:Array = null;
		
		override public function get propertiesArray():Array
		{
			if(_propertiesArray)
			{
				return _propertiesArray;
			}
			
			_propertiesArray = super.propertiesArray;
			for(var name:String in defaultValue)
			{
				if(!ArrayUtil.containsValue(_propertiesArray, name))
				{
					_propertiesArray.push(name);
				}
			}
			return _propertiesArray;
		}
		
		public function AxisBase()
		{
			super();
		}
		
		override public function init():void
		{
			super.init();
			
			ticksContainer = new ChartObject();
			labelContainer = new ChartObject();
			
			ticksContainer.relateToParent = true;
			labelContainer.relateToParent = true;
			
			addChildAt(ticksContainer, 0);
			addChildAt(labelContainer, 1);
		}
		
		override public function getDefaultValue(name:String):*
		{
			return (defaultValue[name] === undefined) ? super.getDefaultValue(name) : defaultValue[name];
		}
		
		override public function update(callAfterUpdate:Boolean=true):Boolean
		{
			if(!super.update(false))
			{
				return false;
			}
			
			if(isTicksChange)
			{
				ticksContainer.clear();
				if(ticksArray is Array)
				{
					for each(var tick:Tick in ticksArray)
					{
						if(tick)
						{
							if(tick.needUpdate)
							{
								needUpdate = true;
								return false;
							}
							ticksContainer.addChild(tick);
						}
					}
				}
			}
			if(isLabelsChange)
			{
				labelContainer.clear();
				if(labelsArray is Array)
				{
					for each(var label:Label in labelsArray)
					{
						if(label)
						{
							if(label.needUpdate)
							{
								needUpdate = true;
								return false;
							}
							label.addChild(label.content);
							labelContainer.addChild(label);  
						}
					}
				}
			}
			
			if(callAfterUpdate)
			{
				return afterUpdate();
			}
			return true;
		}
		
		public function calculate():void
		{
			isTicksChange = true;
			isLabelsChange = true;
			needUpdate = true;
			
			_count = max - min;
			if(offset)
			{
				_count++;
			}
			
			_labelCount = Math.ceil((max - min) / steps) + 1;
			
			_tickCount = Math.ceil((max - min) / steps) + 1;
		}
	}
}